﻿Imports Microsoft.SharePoint.Administration.Health
Imports Microsoft.SharePoint
Imports Microsoft.SharePoint.Administration
Imports System.Collections.Generic
Imports System.Xml.Serialization
Imports System.IO
Imports System.Diagnostics
Imports PerformanceLogic


Public Class CPUPerformanceAnalyzer
    Inherits SPHealthAnalysisRule
    Private allCPUData As List(Of CPUMeasurementTest)


    Public Overrides ReadOnly Property Category As Microsoft.SharePoint.Administration.Health.SPHealthCategory
        Get
            Return Microsoft.SharePoint.Administration.Health.SPHealthCategory.Performance

        End Get
    End Property



   
    Public Overrides Function Check() As Microsoft.SharePoint.Administration.Health.SPHealthCheckStatus
        '    Dim aService As New SPWebService("aService", SPFarm.Local)

        Dim aServiceCollection As SPServiceCollection = SPFarm.Local.Services


        Dim aWebApp As SPWebApplication

        Try
            'Here we are determining which web application will store the Performance Data, this has to be the entral administration web application


            If Not SPWebService.AdministrationService.Status = SPObjectStatus.Disabled Then
                Dim anEnum As IEnumerator = SPWebService.AdministrationService.WebApplications.GetEnumerator()

                While anEnum.MoveNext


                    aWebApp = CType(anEnum.Current, SPWebApplication)
                    Exit While

                End While

            End If

            'For Each nextWebApp As SPWebApplication In aWebService.WebApplications

            '    If nextWebApp.IsAdministrationWebApplication = True Then
            '        aWebApp = nextWebApp
            '        Exit For
            '    Else
            '        Return SPHealthCheckStatus.Failed
            '    End If

            'Next
            'here we bring back the performance data and serialize back into objects
            Dim CPUData As String
            Dim allProperties As Hashtable = aWebApp.Properties

            If allProperties.ContainsKey("CPUData") = True Then


                If allProperties("CPUData").ToString.Trim() <> "" Then
                    CPUData = allProperties("CPUData").ToString()
                    allCPUData = PerformanceLogic.CPUTestLogic.ParseCPUData(allProperties("CPUData").ToString())
                Else
                    CPUData = Nothing
                    allCPUData = New List(Of CPUMeasurementTest)

                End If



            Else
                allProperties.Add("CPUData", "")
                CPUData = Nothing
                allCPUData = New List(Of CPUMeasurementTest)
                aWebApp.Update()

            End If


            Dim averages As Dictionary(Of String, Double) = PerformanceLogic.CPUTestLogic.DetermineAverageCPUUse(allCPUData)
            Dim failures As New Dictionary(Of String, Double)

            For Each Server As String In averages.Keys


                If averages(Server) > 80 Then

                    failures.Add(Server, averages(Server))

                End If



            Next

            'If  we've collected less than a full 6 hours worth of data, pass by default
            If DetermineEarliestDate(allCPUData) >= System.DateTime.Now.AddHours(-6) Then
                Return Nothing
                Return SPHealthCheckStatus.Passed
            ElseIf failures.Count > 1 Then
                FailServers(failures)
                Return SPHealthCheckStatus.Failed

            Else
                Return Nothing

                Return SPHealthCheckStatus.Passed
            End If



        Catch ex As Exception

            '   _ErrorLevel = SPHealthCheckErrorLevel.RuleExecutionFailure
            _Explanation = ex.Message & ex.StackTrace
            _Summary = "CPU Performance check could not execute"
            Return SPHealthCheckStatus.Failed

        Finally



        End Try



    End Function


    Private Function DetermineEarliestDate(ByRef allCPUData As List(Of CPUMeasurementTest)) As DateTime

        Dim CpuTestCount As Integer = 1
        Dim EarliestFound As Integer = 1
        For Each aTest As CPUMeasurementTest In allCPUData

            If CpuTestCount <> 1 Then

                If aTest.MeasureMentDate < allCPUData(CpuTestCount - 1).MeasureMentDate Then

                    EarliestFound = CpuTestCount

                End If


            End If


            CpuTestCount += 1

        Next


        Return allCPUData(EarliestFound).MeasureMentDate



    End Function



    Private Sub FailServers(ByVal FailedResults As Dictionary(Of String, Double))

        Dim ServerString As String = ""
        Dim serverCount As Integer = 0
        For Each aServer As String In FailedResults.Values

            ServerString = ServerString & aServer & IIf(serverCount <> FailedResults.Count - 1, ",", "").ToString()
            serverCount += 1



        Next


        ' _ErrorLevel = SPHealthCheckErrorLevel.Warning
        _Explanation = "CPU IS consistently high on the following server(s): " & ServerString
        _Remedy = "Consider adding more servers or CPU's to reduce server load."
        _Summary = "Your server CPU Level has been very high for the past 48 hours on some servers."


    End Sub




    'Private _ErrorLevel As SPHealthCheckErrorLevel = Nothing


    Public Overrides ReadOnly Property ErrorLevel As Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel
        Get
            Return SPHealthCheckErrorLevel.Error
        End Get
    End Property

    Private _Explanation As String
    Public Overrides ReadOnly Property Explanation As String
        Get
            Return _Explanation
        End Get
    End Property

    Private _Remedy As String
    Public Overrides ReadOnly Property Remedy As String
        Get
            Return _Remedy
        End Get
    End Property

    Private _Summary As String = "Your server CPU Level has been very high for the past 48 hours on some servers."
    Public Overrides ReadOnly Property Summary As String
        Get
            Return _Summary
        End Get
    End Property

    Public Overrides ReadOnly Property AutomaticExecutionParameters() As SPHealthAnalysisRuleAutomaticExecutionParameters
        Get

            '  Dim aSchedule As New SPHealthCheckSchedule



            Dim retval As New SPHealthAnalysisRuleAutomaticExecutionParameters()
            retval.Schedule = SPHealthCheckSchedule.Hourly
            retval.Scope = SPHealthCheckScope.Any
            retval.ServiceType = GetType(SPTimerService)

            retval.RepairAutomatically = False

            Return retval
        End Get


    End Property





   
End Class

